import hashlib
import json
import time
import random
import jwt
from django.conf import settings
from django.core.cache import cache
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.utils.decorators import method_decorator

from tools.sms import YunTongXin
from .tasks import task_tesk
from tools.login_dec import login_check
# Create your views here.
from django.views import View
from .models import UserProfile

# class UserView(View):
#     def post(self, request):
#         # add your code here
#         # 如果提取的是字符串，如何拿数据？
#         # request.POST.get(name)
#         # 提交的数据格式是json,如何拿数据？
#         # 1先获取json串
#         json_str = request.body
#         # 2将字符串反序列化为对象
#         py_obj = json.loads(json_str)
#         # 3获取每一个数据
#         username = py_obj['username']
#         password_1 = py_obj['password_1']
#         password_2 = py_obj['password_2']
#         phone = py_obj['phone']
#         print(username,  password_1, password_2, phone)
#         # 1 检查输入的数据（用户名称为空的检查）
#         if not username:
#             result = {'code': 10100, 'error': '用户名称为空'}
#             return JsonResponse(result)
#
#         # 2 两次密码要一致
#         if password_1 != password_2:
#             result = {'code': 10101, 'error': '两次密码不一致'}
#             return JsonResponse(result)
#         # 验证码的比较（用户输入的和生成的比较）
#         # 1从前端获取用户输入的验证码
#         sms_num = py_obj['sms_num']
#
#         # 2从redis中获取保存的验证码
#         cache_key = "sms_%s" % phone
#         code = cache.get(cache_key)
#         # 3 对比两个验证码，如果不相等，提示验证码错误
#         if int(sms_num) != code:
#             result = {'code': 10105, 'error': '验证码错误'}
#             return JsonResponse(result)
#
#         # 3 计算密码的hash值（md5）
#         md5 = hashlib.md5()
#         md5.update(password_1.encode())
#         password_h = md5.hexdigest()
#         # 4数据入库
#         # 用try吗？也要try,'error':用户名一被占用
#         # UserProfile.objects.create(...)
#         try:
#             UserProfile.objects.create(
#                 username=username,
#                 password=password_h,
#                 phone=phone,
#             )
#         except:
#             result = {'code': 10102, 'error': '用户名被占用'}
#             return JsonResponse(result)
#
#         # 注册成功，意味着完成了创建，并登录意味着要做登录验证后的事情
#         # 生成token,返回给客户端浏览器存储token.
#         token = make_token(username)  # token有的机子是字节串（教学环境,本机），有的是字符串
#         token = token.decode()  # 可以打印检测，需要字符串
#         return JsonResponse({'code': 200, 'username': username,
#                              'data': {'token': token}})
#
#     @method_decorator(login_check)
#     def put(self, request, username):
#         # add your code here [5分钟]
#         # 1 获取前端提交的数据
#         json_str = request.body
#         # 2 将收到的json串反序列化为对象
#         py_obj = json.loads(json_str)
#         # 3 从request.myuser中获取要修改的用户
#         user = request.myuser
#         # 4 修改,使用从前端获取的数据修改对象
#         user.nickname = py_obj['nickname']
#         user.sign = py_obj['sign']
#         user.info = py_obj['info']
#         # 5. 保存 user.save()
#         user.save()
#         return JsonResponse({'code': 200})
#
#
# def make_token(username, expire=3600 * 24):
#     key = settings.JWT_TOKEN_KEY
#     now = time.time()
#     payload = {'username': username, 'exp': now + expire}
#     return jwt.encode(payload, key)
#
# def sms_view(request):
#     json_str=request.body
#     py_obj=json.loads(json_str)
#     # 　１获取手机号
#     phone=py_obj['phone']
#     # print(phone)
#     # 生成键
#     cache_key = "sms_%s"%phone
#     # 2生成随机验证码
#     code = random.randint(1000, 9999)
#     # print(code)
#     # 将验证码写入redis中
#     cache.set(cache_key,code,65)
#     # 3发送短息验证请求(同步)
#     # x=YunTongXin(settings.SMS_ACCOUNT_ID,
#     #              settings.SMS_ACCOUNT_TOKEN,
#     #              settings.SMS_APP_ID,
#     #              settings.SMS_TEMPLATE_ID)
#     # res =x.run(phone,code)
#
#     # 异步
#     task_tesk.delay(phone,code)
#     # print(res)
#     return JsonResponse({'code': 200})
#
# @login_check
# def user_avatar(request, username):
#     if request.method != 'POST':
#         return HttpResponse('请求方式必须是post')
#     # add your code here
#     # 1 查 2 改 3 保存
#     user = request.myuser
#     user.avatar = request.FILES['avatar']
#     user.save()
#     return JsonResponse({'code': 200})



class UserView(View):
    def get(self, request, username=None):
        if username:
            # 返回某个用户信息
            try:
                user = UserProfile.objects.get(username=username)
            except:
                result = {'code': 10103, 'error': '用户不存在'}
                return JsonResponse(result)
            # 1. 获取查询字符串中所有变量的名称
            keys = request.GET.keys()
            if keys:
                data = {}
                for k in keys:
                    if k == 'password':
                        continue
                    if hasattr(user, k):
                        data[k] = getattr(user, k)
                result = {'code': 200,
                          'username': username,
                          'data': data}
            else:
                result = {'code': 200,
                          'username': username,
                          'data': {
                              'info': user.info,
                              'sign': user.sign,
                              'nickname': user.nickname,
                              'avatar': str(user.avatar)
                          }}
            return JsonResponse(result)


        else:
            # 返回所有用户信息
            return HttpResponse('-get users-')

    def post(self, request):
        # add your code here
        # 如果提交的是字符串,如何拿数据
        # request.POST.get(name)
        # 提交的数据格式是json,如何拿数据
        # 1先获取json串
        json_str = request.body
        # 2 将字符串反序列化为对象
        py_obj = json.loads(json_str)
        # 3 获取每一个数据
        username = py_obj['username']
        email = py_obj['email']
        password_1 = py_obj['password_1']
        password_2 = py_obj['password_2']
        phone = py_obj['phone']

        print(username, email, password_1, password_2, phone)
        # 1 用户名称为空的检查
        if not username:
            result = {'code': 10100, 'error': '用户名称为空!'}
            return JsonResponse(result)
        # 2 两次密码要一致
        if password_1 != password_2:
            result = {'code': 10101, 'error': '两次密码不一致!'}
            return JsonResponse(result)

        #  验证码的比较(用户输入的和生成的对比)
        # [10分钟]:16:55回来
        # 1 从前端获取用户输入的验证码
        sms_num = py_obj['sms_num']
        # 2 从redis中获取保存的验证码
        cache_key = 'sms_%s' % phone
        code = cache.get(cache_key)
        # 3 对比这两个验证码,如果不相等,提示验证码错误,直接返回
        if int(sms_num) != code:
            result = {'code': 10105,
                      'error': '验证码错误'}
            return JsonResponse(result)

        # 3 计算密码的hash值(md5)
        md5 = hashlib.md5()
        md5.update(password_1.encode())
        password_h = md5.hexdigest()
        # 4 数据入库
        # 用try吗?也要try,'error':用户名已经被占用
        # UserProfile.objects.create(...)
        try:
            UserProfile.objects.create(username=username,
                                       password=password_h,
                                       email=email,
                                       phone=phone)
        except:
            result = {'code': 10102, 'error': '用户名被占用'}
            return JsonResponse(result)

        # 注册成功,意味着完成了创建,并登录意味着要做登录验证后的事情
        # 生成token,返回给客户端浏览器存储token.
        token = make_token(username)
        token = token.decode()
        return JsonResponse({'code': 200, 'username': username,
                             'data': {'token': token}})

    @method_decorator(login_check)
    def put(self, request, username):
        # add your code here [5分钟]
        # 1 获取前端提交的数据
        json_str = request.body
        # 2 将收到的json串反序列化为对象
        py_obj = json.loads(json_str)
        # 3 从request.myuser中获取要修改的用户
        user = request.myuser
        # 4 修改,使用从前端获取的数据修改对象
        user.nickname = py_obj['nickname']
        user.sign = py_obj['sign']
        user.info = py_obj['info']
        # 5. 保存 user.save()
        user.save()
        return JsonResponse({'code': 200})


def make_token(username, expire=3600 * 24):
    key = settings.JWT_TOKEN_KEY
    now = time.time()
    payload = {'username': username,
               'exp': now + expire}
    return jwt.encode(payload, key)


@login_check
def user_avatar(request, username):
    if request.method != 'POST':
        return HttpResponse('请求方式必须是post')
    # add your code here
    # 1 查 2 改 3 保存
    user = request.myuser
    user.avatar = request.FILES['avatar']
    user.save()
    return JsonResponse({'code': 200})


def sms_view(request):
    json_str = request.body
    print(json_str)
    py_obj = json.loads(json_str)
    # 1 获取手机号
    phone = py_obj['phone']
    # 生成键
    cache_key = 'sms_%s' % phone
    # 2 生成随机验证码
    code = random.randint(1000, 9999)
    print('验证码是%s'%code)
    # 将验证码写入到redis中
    cache.set(cache_key, code, 65)
    # 3 发送短信验证请求(同步)
    # x = YunTongXin(settings.SMS_ACCOUNT_ID,
    #                settings.SMS_ACCOUNT_TOKEN,
    #                settings.SMS_APP_ID,
    #                settings.SMS_TEMPLATE_ID)
    # res = x.run(phone, code)
    # print(res)
    #异步
    task_tesk.delay(phone, code)
    return JsonResponse({'code': 200})
